/*
 *
 *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 */
import { Button, Card, Form, Layout } from 'tea-component';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
  useFetchChainContractDetail,
  useFetchContractRuntimeTypeList,
  useModifyChainContractDetail,
} from '../../../common/apis/chains/hooks';
import { useHistory, useParams } from 'react-router-dom';
import GlossaryGuide from '../../../common/components/glossary-guide';
import { ChainParamsInput, ChainParamsText } from '../chain-invoke-contracts';
import {
  ChainContractMethodsDecoded,
  ContractStatusEnum,
  InvokeRecordRequest,
} from '../../../common/apis/chains/interface';
import { delay, safeParseArrayStr } from '../../../utils/common';
import { NoUndefinedField } from '../../../common/interface';
import { Controller, useForm } from 'react-hook-form';
import { UploadFile } from '../../../common/components/upload-file';

const { Content } = Layout;

export enum ContractRuntimeTypeEnum {
  EVM = 5,
}

export default function ContractDetail() {
  const { id: contractId } = useParams<{ id: string }>();
  const history = useHistory();
  const { fetch: fetchContractDetail, detail: contractDetail } = useFetchChainContractDetail();

  const [methodsDecoded, setMethodsDecoded] = useState<ChainContractMethodsDecoded | null>(null);
  const [parameters, setParameters] = useState<NoUndefinedField<InvokeRecordRequest['Parameters']>>([]);
  const { run: modifyContract } = useModifyChainContractDetail();
  const [pageReadonly, setPageReadonly] = useState(false);
  const uploadFileRef = useRef<any>(null);
  const {
    control,
    formState: { isValid },
    getValues,
    setValue,
    trigger,
  } = useForm({ mode: 'onBlur' });

  useEffect(() => {
    if (contractDetail) {
      setMethodsDecoded(safeParseArrayStr(contractDetail.Methods));
      setParameters(safeParseArrayStr(contractDetail.Parameters));
      setPageReadonly(contractDetail.ContractStatus === ContractStatusEnum.ContractRevokeOK.value);
      if (contractDetail.RuntimeType === ContractRuntimeTypeEnum.EVM) {
        setValue('EvmAbiSaveKey', contractDetail.EvmAbiSaveKey);
        uploadFileRef.current.setDefaultValue(contractDetail.AbiName);
      }
      trigger();
    }
  }, [contractDetail]);
  const { runtimeTypeList, run: fetchRuntimeTypeList } = useFetchContractRuntimeTypeList();

  useEffect(() => {
    fetchContractDetail({
      Id: +contractId,
    });
    fetchRuntimeTypeList();
  }, []);

  const onSubmit = useCallback(async () => {
    const values = getValues();
    await modifyContract({
      ...values,
      Id: +contractId,
      Methods: methodsDecoded as ChainContractMethodsDecoded,
    });
    delay(0.5).then(() => history.goBack());
  }, [methodsDecoded, contractId]);
  return (
    <Content>
      <Content.Header
        title={pageReadonly ? '查看合约' : '编辑合约'}
        showBackButton
        onBackButtonClick={history.goBack}
      />
      <Content.Body full>
        <Card>
          <Card.Body>
            <Form>
              <Form.Item label={<GlossaryGuide title={'合约名称'} />}>
                <Form.Text>{contractDetail?.ContractName}</Form.Text>
              </Form.Item>
              <Form.Item label={<GlossaryGuide title={'状态'} />}>
                <Form.Text>
                  {
                    Object.values(ContractStatusEnum).find((item) => item.value === contractDetail?.ContractStatus)
                      ?.text
                  }
                </Form.Text>
              </Form.Item>
              <Form.Item label={<GlossaryGuide title={'当前版本'} />}>
                <Form.Text>{contractDetail?.ContractVersion}</Form.Text>
              </Form.Item>
              <Form.Item label={<GlossaryGuide title={'虚拟机类型'} />}>
                <Form.Text>
                  {
                    runtimeTypeList?.find((item) => item.RuntimeTypeType === contractDetail?.RuntimeType)
                      ?.RuntimeTypeName
                  }
                </Form.Text>
              </Form.Item>
              {contractDetail?.RuntimeType === ContractRuntimeTypeEnum.EVM && (
                <Controller
                  control={control}
                  name="EvmAbiSaveKey"
                  rules={{
                    validate: (value) => {
                      if (!value && uploadFileRef.current?.status === null) {
                        return '请上传合约文件';
                      }
                      if (!value && uploadFileRef.current?.status === 'error') {
                        return '上传合约文件格式不正确';
                      }
                      return undefined;
                    },
                  }}
                  render={({ field, fieldState }) => (
                    <Form.Item
                      status={uploadFileRef.current?.status}
                      label="ABI文件"
                      message={fieldState.error?.message}
                      required
                    >
                      <UploadFile
                        {...field}
                        accept=".abi"
                        ref={uploadFileRef}
                        onSuccess={(key: string | null) => {
                          setValue(field.name, key, {
                            shouldValidate: true,
                          });
                        }}
                      />
                    </Form.Item>
                  )}
                />
              )}
              {parameters.length > 0 && <Form.Item label={<GlossaryGuide title={'额外信息(选填)'} />}></Form.Item>}
            </Form>
            {parameters.length > 0 && (
              <div>
                <ChainParamsText values={parameters} />
              </div>
            )}
            {
              <>
                <Form className={'content-mt-2n'}>
                  <Form.Item label={<GlossaryGuide title={'合约调用方法(选填)'} />}></Form.Item>
                </Form>
                <div>
                  {methodsDecoded &&
                    (pageReadonly || contractDetail?.RuntimeType === ContractRuntimeTypeEnum.EVM ? (
                      <ChainParamsText values={methodsDecoded} />
                    ) : (
                      <ChainParamsInput
                        defaultValues={methodsDecoded}
                        onChange={(params: ChainContractMethodsDecoded) => {
                          setMethodsDecoded(params);
                        }}
                        paramKeys={['MethodName', 'MethodFunc', 'MethodKey']}
                        placeholders={['Method', 'MethodFunc', 'Param，例 key1,key2,key3']}
                      />
                    ))}
                </div>
              </>
            }
            {!pageReadonly && (
              <div className={'content-mt-4n'}>
                <Button type={'primary'} onClick={onSubmit} disabled={!isValid}>
                  确定
                </Button>
                <Button onClick={history.goBack} className={'content-ml-1n'}>
                  取消
                </Button>
              </div>
            )}
          </Card.Body>
        </Card>
      </Content.Body>
    </Content>
  );
}
